﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

////static_cast reinterpret_cast
//int main() {
//	//相近类型用static_cast->意义相似的类型
//	double d = 12.34;
//	int a = static_cast<int>(d);
//	cout << a << endl;
//
//	// 有一定的关联，但是意义不相似的的类型用reinterpret_cast 
//	int* p = reinterpret_cast<int*>(a);
//	return 0;
//}



////const_cast
//int main() {
//	//const int a = 2;
//	//int* p = const_cast<int*>(&a);
//	//*p = 3;
//
//	////当变量被声明为const时，编译器会假定它的值永远不会改变，因此可以进行优化。
//	////在编译时，编译器可能会直接用常量值替换所有对a的引用。
//	//cout << a << endl;//2 被编译器优化为直接输出2
//	//cout << *p << endl;//3 实际上访问了内存中的值
//
//	////地址相同
//	//cout << &a << endl;
//	//cout << p << endl;
//
//
//	////告诉编译器不要优化对该变量的访问，每次读取 a 时都必须从内存中重新加载，
//	////而不是使用寄存器中的缓存或直接替换成常量。
//	//volatile const int a = 2;
//	//int* p = const_cast<int*>(&a);
//	//*p = 3;
//
//	//cout << a << endl;//3
//	//cout << *p << endl;//3 
//
//	//cout << &a << endl;//1
//	//cout << (void*)&a << endl;//012FF93C
//	//cout << (int*)&a << endl;//012FF93C
//	//printf("%p\n", &a);//012FF93C
//	//cout << p << endl;//012FF93C
//
//
//	//使用强制类型转换与const_cast相同
//	const int a = 2;
//	int* p = (int*)&a;
//	*p = 3;
//
//	cout << a << endl;//2
//	cout << *p << endl;//3 
//
//	//地址相同
//	cout << &a << endl;
//	cout << p << endl;
//	return 0;
//}



////隐示类型转换不好的地方
//void insert(size_t pos, char ch) {
//	int end = 10;
//	while (end >= pos) {
//		cout << end << endl;
//		--end;
//	}
//}
//
//int main() {
//	//死循环
//	//size_t 是无符号整数类型，当end递减到-1时会触发隐式类型转换
//	//在比较时，end 会被转换成 size_t
//	insert(0, 'x');
//	return 0;
//}



//dynamic_cast
//必须是多态
class A {
public:
	virtual void f() {}
	int _a = 0;
};
class B : public A {
public:
	int _b = 1;
};

//void fun(A* pa) {
//	//向下转换：直接转换不完全
//	//fun(&a); 是取a对象的地址，但是被强制转换为B* 指针后，
//	//会错误的以为_a后面还有个_b的成员变量，当取去修改_b时，其实修改的已经不是a对象的空间了
//	B* ptr = (B*)pa;
//	ptr->_a++;
//	ptr->_b++;
//}
void fun(A* pa) {
	B* ptr = dynamic_cast<B*>(pa);
	//dynamic_cast的转换：指向父类转换失败，返回空
	if (ptr) {
		ptr->_a++;
		ptr->_b++;
		cout << ptr->_a << " " << ptr->_b << endl;
	}
	else cout << "转换失败" << endl;

}

int main() {
	//B objb;
	//A obja = objb;
	//A& ra = objb;//这里没有转换，因为转换有临时变量，const引用才可以

	//向下转换规则：父类对象不能转换成子类对象，但父类指针和引用可以转换为子类的指针和引用
	A a;
	B b;
	fun(&a);//转换失败
	fun(&b);//1 2
	return 0;
}